
package xmarti.vacaxm.utils;



import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.classic.Session;
import xmarti.vacaxm.exception.ExceptionHibernateVacaxm;

/**
 * Classe que representa a les utilitats imprescindibles per a portar a terme les transaccions a la base de dades<br>
 * També utititats per realitzar tasques comunes d'inserció, modificació i eliminació.
 * @author Xavier Martí Moret 
 *
 */
public class HibernateUtil {

	private static final SessionFactory sessionFactory = buildSessionFactory();
	/**
	 * Crea una sessió per hibernate a partir dels paràmetres del fitxer de configuració
	 * @return
	 */
	private static SessionFactory buildSessionFactory() {
		try {
			// Create the SessionFactory from hibernate.cfg.xml
			return new AnnotationConfiguration().configure()
					.buildSessionFactory();
		} catch (Throwable ex) {
			System.err.println("Initial SessionFactory creation failed." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}
	/**
	 * Obté una sessió 
	 * @return SessionFactory
	 */
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	/**
	 * Insereix un objecte a la base de dades
	 * @param object Objecte a inserir
	 * @return CERT si es realitza l'operació, FALS en cas contrari
         * @throws xmarti.vacaxm.exception.ExceptionHibernateVacaxm
	 */
	public boolean add(Object object) throws ExceptionHibernateVacaxm {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
                boolean state=false;                
		try{			                        
                        session.save(object);                                                
			session.getTransaction().commit();
                        state=true; 
		}catch (Exception e){			
			session.getTransaction().rollback();
			state=false;
                        if (e.getCause().toString().contains("name_UNIQUE")){
                            throw new ExceptionHibernateVacaxm(ExceptionHibernateVacaxm.ERR_INSERT_NAME_UNIQUE);
                        }else{
                            throw new ExceptionHibernateVacaxm(ExceptionHibernateVacaxm.ERR_INSERT);			
                        }                        
		}
		
		return state;
	}
        
	/**
	 * Elimina un objecte de la base de dades
	 * @param object objecte a eliminar
         * @return 
         * @throws xmarti.vacaxm.exception.ExceptionHibernateVacaxm 
	 */
	public boolean delete(Object object) throws ExceptionHibernateVacaxm{
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		boolean result=false;
                try{
                    session.delete(object);                    
                    session.getTransaction().commit();
                    result=true; 
                }catch(HibernateException he){
                    session.getTransaction().rollback();
                    
                    if (he.getCause().toString().contains("foreign key")){
                        throw new ExceptionHibernateVacaxm(ExceptionHibernateVacaxm.ERR_REMOVE_FOREIGN_KEY);						
                    }else{
                        throw new ExceptionHibernateVacaxm(ExceptionHibernateVacaxm.ERR_REMOVE);
                    }
                }
                return result;
	}
	/**
	 * Modifica un objecte de la base de dades
	 * @param object Objecte a modificar
	 * @return CERT si es realtiza l'operació, FALS en cas contrari
         * @throws xmarti.vacaxm.exception.ExceptionHibernateVacaxm
	 */
	public boolean  update(Object object) throws ExceptionHibernateVacaxm{
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		try{
			session.merge(object);
			session.getTransaction().commit();
		}catch (Exception e){
			session.getTransaction().rollback();			
                        throw new ExceptionHibernateVacaxm(ExceptionHibernateVacaxm.ERR_UPDATE);						
                        						
		}
		return true;
	}
        public boolean update(Object object1, Object object2) throws ExceptionHibernateVacaxm {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
                boolean state=false;
		try{			                        
                        session.merge(object1);
                        session.merge(object2);
			session.getTransaction().commit();
                        state=true; 
		}catch (Exception e){			
			session.getTransaction().rollback();
			state=false;
                        throw new ExceptionHibernateVacaxm(e.getMessage());                
		}
		
		return state;
	}
        public  <T> T getObjectById(Serializable id, Class<T> entityClass) throws ExceptionHibernateVacaxm {        
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            T recoveredObject = null;
            try
            {                
                recoveredObject = (T)session.get(entityClass, id);              
            }
            catch (HibernateException he)
            {
                
                throw new ExceptionHibernateVacaxm(ExceptionHibernateVacaxm.ERR_SELECT);						
            }
            
            return recoveredObject;
        }
        
        public  <T> List<T> getList(Class<T> entityClass) throws ExceptionHibernateVacaxm {        
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            List<T> resultList = new ArrayList<T>();
            try
            {            
                resultList= session.createQuery("FROM " + entityClass.getSimpleName()).list();
            }
            catch (HibernateException he)
            {
                throw new ExceptionHibernateVacaxm(ExceptionHibernateVacaxm.ERR_SELECT);
            }
            return resultList;
        }
         public  <T> List<T> getListActive(Class<T> entityClass) throws ExceptionHibernateVacaxm {        
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            List<T> resultList = null;
            try
            {            
                resultList= session.createQuery("FROM " + entityClass.getSimpleName()+ " e where e.active=true").list();
            }
            catch (HibernateException he)
            {
                throw new ExceptionHibernateVacaxm(ExceptionHibernateVacaxm.ERR_SELECT);
            }
            return resultList;
        }
         
}
